home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ada
/
gwuada_9.zip
/
LOAD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-27
|
15KB
|
472 lines
/*
* Copyright (C) 1985-1992 New York University
*
* This file is part of the Ada/Ed-C system. See the Ada/Ed README file for
* warranty (none) and distribution info and also the GNU General Public
* License for more details.
*/
/* load.c - procedures to load to libraries and axq files */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "config.h"
#include "int.h"
#include "segment.h"
#include "slot.h"
#include "ivars.h"
#include "ifile.h"
#include "miscp.h"
#include "libfp.h"
#include "axqrp.h"
#include "loadp.h"
static void init_predef();
static void init_library(IFILE *, char *);
static char *unit_name_name(char *);
static int *unit_list_new();
static void unit_list_copy(int *, int *);
static int unit_list_next(int *);
static int in_loaded(char *);
/* Various sets and maps in the SETL version are represented using
* strings in the C version. This is possible since they all have as
* their domain unit_numbers, and the total number of unit_numbers is
* known before these are needed. The initial values of these items
* are set by
* s = unit_list_new().
* Once defined, s[i] is YES if unit i is in the set, NO otherwise.
* These sets are kept as a vector of (short) integers, with the
* first (zeroth) element giving the number of elements, in much the
* way is tuples are represented in the other parts of the compiler.
*/
#define YES 1
#define NO 0
static char **file_number;
static int **PRECEDES_MAP;
static char **unit_names;
static int unit_count;
static int interfaced_unit = 0;
static int obsolete_error = FALSE;
/* The following struct is used main a list of the units actually loaded. */
struct axq_loaded {
struct axq_loaded *loaded_next;
char *loaded_name;
};
static struct axq_loaded *ll_head; /* pointer to head of list */
static void init_predef() /*;init_predef*/
{
int i;
static char *predef_units[] = {
"spSYSTEM", "spIO_EXCEPTIONS", "spSEQUENTIAL_IO",
"boSEQUENTIAL_IO", "spDIRECT_IO", "boDIRECT_IO",
"spTEXT_IO", "boTEXT_IO", "spCALENDAR", "boCALENDAR",
"ssUNCHECKED_DEALLOCATION", "suUNCHECKED_DEALLOCATION",
"ssUNCHECKED_CONVERSION", "suUNCHECKED_CONVERSION"
};
/* Set values for unit_names, file_number and PRECEDES information for
* predefined compilation units, since they do not appear in any library
*/
/* allocate unit names - recalling it is ones origin */
unit_count = 14;
unit_names = (char **) emalloct((unit_count + 1) * sizeof(char *),
"unit_names");
PRECEDES_MAP = (int **) emalloct(sizeof(char **) *(unit_count + 1),
"precedes_map");
PRECEDES_MAP[0] = (int *) unit_count;
file_number = (char **) emalloct(sizeof(char **) *(unit_count + 1),
"file_number");
for (i = 1; i <= unit_count; i++) {
unit_names[i] = predef_units[i - 1];
file_number[i] = "0";
PRECEDES_MAP[i] = unit_list_new();
}
}
void load_lib(char *filename, IFILE *libfile, Axq axq, char *main_unit,
char **argv) /*;load_lib*/
{
/* This procedure looks for the main unit
* and loads it, together with all units on which it depends directly
* or indirectly. Dependences are taken from map precedes.
*/
struct axq_loaded *ll_new;
int *main_units, *bound_units, *new_main_units, *to_read, *precedes;
int unitn;
int i, name, pi;
int is_predef_unit;
int nmain_units;
char *idle_task_name, *unit_file;
IFILE * axqfile;
char exename[100];
char *PREDEFNAME;
char *file_name, *l_name, *t_name;
ll_head = (struct axq_loaded *) 0; /* Initially, no files loaded */
init_library(libfile,main_unit);
main_units = unit_list_new();
bound_units = unit_list_new();
for (i = 1; i <= unit_count; i++) {
if (streq(unit_name_type(unit_names[i]), "ma"))
main_units[i] = YES;
}
if (main_unit != (char *) 0) {
/* main_units := {[x,y]: [x,y] in main_units
* | y = '_'+MAINUNIT+'_idle_task'};
*/
idle_task_name = strjoin(main_unit, "_idle_task");
for (name = 1; name <= unit_count; name++) {
if (main_units[name] == NO)
continue;
if (streq(idle_task_name, unit_names[name]+2))
bound_units[name] = YES;
}
unit_list_copy(main_units, bound_units);
}
nmain_units = 0;
for (i = 1; i <= main_units[0]; i++)
if (main_units[i]) nmain_units++;
if (nmain_units == 0) {
printf("*** Unbound library, execution not allowed\n");
exit(RC_ERRORS);
}
else if (nmain_units > 1) {
printf("*** More than one main program in library\n");
printf(" Use option: -m(one of the following)\n");
for (name = 1; name <= unit_count; name++) {
if (main_units[name] == NO)
continue;
unit_names[name][strlen(unit_names[name])-10] = '\0';
/* name of the form _xxx_idle_task, print only xxx */
printf(" %s\n", unit_names[name]+2);
}
exit(RC_ERRORS);
}
else {
#ifndef INTERFACE
#ifdef SUPPORT_PRAGMA_INTERFACE
/* at this point, if the main binding unit is interfaced, we run
* the executable which has been built with the procedure interface
*/
if (interfaced_unit != 0) {
sprintf(exename,"%s%s%s.exe",filename,DIR_DELIMITER,
file_number[interfaced_unit]);
execvp(exename,argv);
}
#endif
#endif
if (obsolete_error) {
printf(
"*** Main binding unit obsolete, please recompile or rebind \n");
exit(RC_ERRORS);
}
to_read = unit_list_new();
while(unit_list_next(main_units)) {
for (name = 1; name <= unit_count; name++) {
if (main_units[name] == NO)
continue;
to_read[name] = YES;
}
/* main_units := {} +/{ precedes{u} : u in main_units}; */
new_main_units = unit_list_new();
/* for name in main_units */
for (name = 1; name <= unit_count; name++) {
if (main_units[name] == NO)
continue;
precedes = PRECEDES_MAP[name];
for (pi = 1; pi <= unit_count; pi++) {
if (precedes[pi] == NO)
continue;
new_main_units[pi] = YES;
}
}
unit_list_copy(main_units, new_main_units);
}
while((unitn = unit_list_next(to_read))) {
to_read[unitn] = NO; /* remove from set */
if (unitn == 0) {
/* junk unit number - binder shouldn't be putting this out */
printf("load.c: skipping 0 case\n");
continue;
}
if (unitn <= unit_count /* false if "ghost package body" */
&&(!in_loaded(file_number[unitn]))) {
unit_file = (char *) file_number[unitn];
file_name = unit_file;
is_predef_unit = streq(unit_file,"0");
if (is_predef_unit) {
PREDEFNAME = predef_env();
l_name = libset(PREDEFNAME); /* use predef library */
file_name = "predef";
}
axqfile = ifopen(file_name, "axq", "r", 0);
read_axq(axqfile, axq);
ifclose(axqfile);
if (is_predef_unit)
t_name = libset(l_name); /* restore user library */
if (!in_loaded(unit_file))
ll_new = (struct axq_loaded *)
smalloc(sizeof(struct axq_loaded));
ll_new->loaded_next = ll_head;
ll_new->loaded_name = unit_file;
ll_head = ll_new;
}
} /* while */
}
}
static void init_library(IFILE *ifile, char *main_unit) /*;init_library*/
{
/*
* retrieve information from ifile
*/
int i, j, n, m, unumber,cur_level;
int ignore;
int punit;
char *uname, *aisname;
int *precedes;
char *main_binding_unit = (char *)0;
int units_lib;
int is_interfaced,comp_status;
init_predef();
ll_head = (struct axq_loaded *) 0;
if (ifile == (IFILE *) 0) {
printf("*** library is empty\n");
exit(RC_ERRORS);
}
units_lib = getnum(ifile, "lib-unit-count");
unit_count = getnum(ifile, "lib-unit_num");
getnum(ifile, "lib-empty-slots"); /* ignore */
getstr(ifile, "lib-tmp-str"); /* ignore */
unit_names = (char **) erealloct((char *)unit_names,
(unit_count+1) * sizeof(char **), "unit_names-re");
file_number = (char **) erealloct((char *)file_number,
sizeof(char **) *(unit_count+1),"file_number-re");
#ifndef INTERFACE
if (main_unit != (char *)0) {
/* a main unit was specified */
main_binding_uni